package Web.e4;

import java.io.*;
import java.net.*;
import java.util.*;

// 多线程处理客户端请求
class ClientHandler implements Runnable {
    private Socket sock;
    private String baseDir;

    public ClientHandler(Socket sock, String baseDir) {
        this.sock = sock;
        this.baseDir = baseDir;
    }

    @Override
    public void run() {
        BufferedReader in = null;
        OutputStream out = null;
        FileInputStream infile = null;

        try {
            in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
            out = sock.getOutputStream();

            // 读取HTTP请求头
            String requestLine = in.readLine();
            if (requestLine == null) {
                return;
            }

            System.out.println("收到请求: " + requestLine);
            String[] parts = requestLine.split(" ");
            if (parts.length < 3) {
                sendErrorResponse(out, 400, "Bad Request");
                return;
            }

            String method = parts[0];
            String path = parts[1];
            String protocol = parts[2];

            // 跳过请求头
            String header;
            while ((header = in.readLine()) != null && !header.isEmpty()) {
                // 可以在这里处理请求头信息
            }

            // 处理不同的HTTP方法
            switch (method) {
                case "GET":
                    handleGet(out, path);
                    break;
                default:
                    sendErrorResponse(out, 501, "Not Implemented");
            }

        } catch (IOException e) {
            System.err.println("处理请求错误: " + e.getMessage());
        } finally {
            try {
                if (infile != null) infile.close();
                if (in != null) in.close();
                if (out != null) out.close();
                if (sock != null) sock.close();
            } catch (IOException e) {
                // 忽略关闭时的异常
            }
        }
    }

    // 处理GET请求
    private void handleGet(OutputStream out, String path) throws IOException {
        File file = getFileFromPath(path);
        if (!file.exists() || !file.isFile()) {
            sendErrorResponse(out, 404, "Not Found");
            return;
        }

        // 发送HTTP响应头
        sendResponseHeaders(out, 200, "OK", file.length(), getContentType(file.getName()));
        
        // 发送文件内容
        byte[] buff = new byte[1024];
        try (FileInputStream infile = new FileInputStream(file)) {
            int n;
            while ((n = infile.read(buff)) != -1) {
                out.write(buff, 0, n);
            }
        }
        out.flush();
    }




    // 发送错误响应
    private void sendErrorResponse(OutputStream out, int statusCode, String reason) throws IOException {
        String response = "HTTP/1.1 " + statusCode + " " + reason + "\r\n";
        response += "Content-Type: text/html\r\n";
        response += "Connection: close\r\n";
        response += "\r\n";
        response += "<html><body><h1>" + statusCode + " " + reason + "</h1></body></html>";
        out.write(response.getBytes());
        out.flush();
    }

    // 发送响应头
    private void sendResponseHeaders(OutputStream out, int statusCode, String reason, 
                                    long contentLength, String contentType) throws IOException {
        String headers = "HTTP/1.1 " + statusCode + " " + reason + "\r\n";
        headers += "Content-Type: " + contentType + "\r\n";
        headers += "Content-Length: " + contentLength + "\r\n";
        headers += "Connection: close\r\n";
        headers += "\r\n";
        out.write(headers.getBytes());
    }

    // 根据路径获取文件
    private File getFileFromPath(String path) {
        // 处理根路径
        if (path.equals("/")) {
            path = "/index.html";
        }
        
        // 构建文件路径
        String filePath = baseDir + path.replace('/', File.separatorChar);
        return new File(filePath);
    }

    // 根据文件名获取内容类型
    private String getContentType(String fileName) {
        if (fileName.endsWith(".html") || fileName.endsWith(".htm")) {
            return "text/html";
        } else if (fileName.endsWith(".txt")) {
            return "text/plain";
        } else if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
            return "image/jpeg";
        } else if (fileName.endsWith(".png")) {
            return "image/png";
        } else if (fileName.endsWith(".css")) {
            return "text/css";
        } else if (fileName.endsWith(".js")) {
            return "application/javascript";
        }
        return "application/octet-stream";
    }
}

// 主服务器类
public class Phttpd {
    public static void main(String[] args) {
        // 检查参数
        if (args.length != 1) {
            System.err.println("用法: java Phttpd <网页根目录>");
            System.exit(1);
        }

        ServerSocket servsock = null;
        try {
            // 创建服务器套接字，监听800端口
            servsock = new ServerSocket(800, 300);
            System.out.println("服务器启动，监听端口800...");
            
            String baseDir = args[0];
            // 检查目录是否存在
            File dir = new File(baseDir);
            if (!dir.exists() || !dir.isDirectory()) {
                System.err.println("错误: 目录不存在或不是有效的目录");
                System.exit(1);
            }

            // 循环接受客户端连接
            while (true) {
                Socket sock = servsock.accept();
                System.out.println("新连接: " + sock.getInetAddress().getHostAddress());
                
                // 创建新线程处理客户端请求
                Thread handler = new Thread(new ClientHandler(sock, baseDir));
                handler.start();
            }
        } catch (IOException e) {
            System.err.println("服务器错误: " + e.getMessage());
        } finally {
            try {
                if (servsock != null) {
                    servsock.close();
                }
            } catch (IOException e) {
                // 忽略关闭时的异常
            }
        }
    }
}